#include "tlv_reader.h"
#include <cstring>

TLVReader::TLVReader(const TLVBuffer& buffer) : buffer_(buffer) {}

std::optional<uint8_t> TLVReader::readUint8(size_t offset) {
    TLV item;
    if (!buffer_.readTLV(offset, item) || item.type != TLVType::UINT8 || item.length != 1)
        return std::nullopt;
    return item.value[0];
}

std::optional<uint16_t> TLVReader::readUint16(size_t offset) {
    TLV item;
    if (!buffer_.readTLV(offset, item) || item.type != TLVType::UINT16 || item.length != 2)
        return std::nullopt;
    uint16_t val;
    std::memcpy(&val, item.value.data(), 2);
    return val;
}

std::optional<uint32_t> TLVReader::readUint32(size_t offset) {
    TLV item;
    if (!buffer_.readTLV(offset, item) || item.type != TLVType::UINT32 || item.length != 4)
        return std::nullopt;
    uint32_t val;
    std::memcpy(&val, item.value.data(), 4);
    return val;
}

std::optional<std::string> TLVReader::readString(size_t offset) {
    TLV item;
    if (!buffer_.readTLV(offset, item) || item.type != TLVType::STRING)
        return std::nullopt;
    return std::string(item.value.begin(), item.value.end());
}

std::optional<std::vector<uint8_t>> TLVReader::readBlob(size_t offset) {
    TLV item;
    if (!buffer_.readTLV(offset, item) || item.type != TLVType::BLOB)
        return std::nullopt;
    return item.value;
}
